package com.ipharma.gui;

import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;

import oracle.jdeveloper.layout.GridBagConstraints2;

import com.ipharma.McdError;
import com.ipharma.McdPrs;
import com.ipharma.config.Config;
import com.ipharma.dto.Product;


/**
 * A Swing-based top level window class.
 * <P>
 * @author JorgE.H
 */
public class GUIExtraction extends GUIOperation
{
  /**
   * The Layouts.
   */
  GridBagLayout layoutBase = new GridBagLayout();
  Font fontButton = new Font( "Dialog", 1, 14 );

  /**
   * The main panel.
   */
  GUIButtonPanel jPanelButtons;
  GUITransactionExtract jPanelTransactions;
  GUIBarCode jPanelBarCode;
  GUIButtonImage jButtBack;
  GUIButtonImage jButtExtract;

  /**
   * Attributes
   */
  // total quantity of dispensed products in the basket
  int li_totalqty =0;

  /**
   * Constructs a new instance.
   */
  public GUIExtraction( GUIWindow pContainer )
  {
    super( pContainer );
    try
    {
      jbInit();
    }
    catch ( Exception e )
    {
      McdError.add( e );
    }
  }

  /**
   * Initializes the state of this instance.
   */
  private void jbInit() throws Exception
  {
    this.setLayout( layoutBase );
    this.setBackground( Colors.ETN_BACK );

    // buttons
    jButtBack = new GUIButtonImage( Images.buttChange, Images.buttChangeDn );
    jButtBack.setDisabledIcon( Images.buttChangeOff );
    jButtBack.addActionListener( new GUIExtraction_jButtBack_actionAdapter( this ) );
    jButtExtract = new GUIButtonImage( Images.buttExtract, Images.buttExtractDn );
    jButtExtract.addActionListener( new GUIExtraction_jButtExtract_actionAdapter( this ) );

    // panel: Transactions
    jPanelTransactions = new GUITransactionExtract( this );
    jPanelTransactions.setRequestFocusEnabled( false );

    // panel: BarCode
    jPanelBarCode = new GUIBarCode( this );
    jPanelBarCode.requestFocus();

    // panel: Buttons
    /*DispenserService service = Helper.getDispenserService();
    productos = service.getProductosDelDispenser(new Long(this.dispenserId));*/
    
    jPanelButtons = new GUIButtonPanel( this, theDispenser.getProducts() );
    jPanelButtons.setRequestFocusEnabled( false );

    // adds objects to panel
    this.add( jPanelButtons, new GridBagConstraints2( 0, 0, 1, 4, 5.0, 1.0,
        GridBagConstraints.WEST, GridBagConstraints.BOTH, Texts.panelMargin, 0, 0 ) );
    this.add( jButtBack, new GridBagConstraints2( 1, 0, 1, 1, 0.0, 0.0,
        GridBagConstraints.EAST, GridBagConstraints.BOTH, Texts.buttMargin, 0, 0 ) );
    this.add( jPanelTransactions, new GridBagConstraints2( 1, 1, 1, 1, 0.1, 1.0,
        GridBagConstraints.EAST, GridBagConstraints.BOTH, Texts.transMargin, 0, 0 ) );
    this.add( jButtExtract, new GridBagConstraints2( 1, 2, 1, 1, 0.0, 0.0,
        GridBagConstraints.EAST, GridBagConstraints.BOTH, Texts.buttMargin, 0, 0 ) );
    this.add( jPanelBarCode, new GridBagConstraints2( 1, 3, 1, 1, 0.1, 0.0,
        GridBagConstraints.SOUTH, GridBagConstraints.BOTH, Texts.barCodeMargin, 0, 0 ) );
  }

  /**
   * Starts execution
   */
  public void start()
  {
    try
    {
      // sets status bar message
      ((GUIMenu)myContainer).setStatusMsg( Texts.ETN_STS );

      // refreshes buttons if changed
      if ( ((GUIMenu)myContainer).dbChanged );
      {
        this.jPanelButtons.refresh( theDispenser.getProducts() );
        ((GUIMenu)myContainer).dbChanged = false;
      }

      // sets assignment
      assign = ((GUIMenu)myContainer).assign;
      this.jPanelTransactions.setAssignment( assign );

      // if operation mode is without assignment, disables cancel button
      Config config = (Config) theSess.get(McdPrs.CONFIG);
      if ( !config.getOperationMode().equals( McdPrs.withAssign ) )
        this.jButtBack.setEnabled( false );

      // sets focus on bar code detector text field
      jPanelBarCode.setFocus();
      this.setVisible( true );
    }
    catch ( Exception e )
    {
      McdError.add( e );
    }
  }

  /**
   * Selects a product into transaction
   * @param pProd Button instance pushed
   * @return int quantity selected
   */
  public int selectProduct( Product pProd )
  {
    int li_qty = 0,
        li_alert = -1;
    String ls_quest;
    Product l_newProd;
    GUIQuantifier l_qtyDialog;
    GUIConfirmer l_sureDialog, l_extOkDialog;

    try
    {
      // stop timer, dialogs controls their own timer
      myContainer.stopTimer();
      l_newProd = pProd;
      // selects quantity calling quantifier dialog
      l_qtyDialog = new GUIQuantifier( this, Texts.APN_OPERATIONS[this.getType()], true );
      l_qtyDialog.setProduct( l_newProd, false );
      Config config = (Config) theSess.get(McdPrs.CONFIG);
      l_qtyDialog.start(new Long(config.getTimeout()).longValue() );
      if ( l_qtyDialog.hasExpired() ) // time expired
      {
        myContainer.timeout();
        return 0;
      }
      // li_qty keeps selected quantity
      li_qty = Integer.parseInt( l_qtyDialog.getSelection() );
      // confirms extraction
      if ( li_qty <= 0 )
      {
        // reset timer
        myContainer.startTimer();
        return 0;
      }
      else
      {
        // l_newProd keeps final amount after extraction
        l_newProd.setQuantity( l_newProd.getQuantity() - li_qty );

        // real extraction
        int li_pretendedQty = li_qty;
        try
        {
          theDispenser.doExtract( l_newProd, li_qty );
          li_totalqty ++;
        }
        catch ( Exception e )
        {
          McdError.add( e );
        }
        if ( !theDispenser.dispensedOk() )
        {
          // error extracting product
          li_alert = McdPrs.altExtractError;
          li_qty = 0;
        }
        else
        {
          // updates DB
          theDispenser.updateExtract( l_newProd, li_qty );
          ((GUIMenu)myContainer).dbChanged = true;
        }
        // registers transaction
        this.jPanelTransactions.addProduct( l_newProd, li_pretendedQty );
        this.jPanelTransactions.endTransaction( li_alert );
        Config config2 = (Config) myContainer.theSess.get(McdPrs.CONFIG);
        if ( li_totalqty == Integer.parseInt((String)  config2.getMaxProdOnBasket()) ) downBasket();

      }

      // reset timer
      myContainer.startTimer();
    }
    catch ( Exception e )
    {
      McdError.add( e );
    }
    // update stock
    return li_qty;
    
  }

  /**
   * Selects a product through external device
   * @param pCode product code selected
   * @return true if product is valid, false otherwise
   */
  public boolean externalSelection( String pCode )
  {
    try
    {
      Product l_prod = getSelectedProduct( pCode );

      if ( l_prod == null )
        return false;

      int li_qty = this.selectProduct( l_prod );
      if ( li_qty > 0 )
      {
        // updates quantity on screen
        jPanelButtons.virtualPushed( l_prod );
      }
      return true;
    }
    catch ( Exception e )
    {
      McdError.add( e );
    }
    return false;
     
  }

  /**
   * Returns the type of operation
   * @return type of operation
   */
  public int getType()
  {
    return McdPrs.extractId;
  }

  /**
   * Returns the product matching pCode
   * @param pCode product code
   * @return the Product object
   */
  public Product getSelectedProduct( String pCode )
  {
    try
    {
      return theDispenser.getProduct( pCode );
       
    }
    catch ( Exception e )
    {
      McdError.add( e );
    }
    return null;
  }

  void jButtBack_actionPerformed( ActionEvent e )
  {
    // jumps to assignment screen
    ((GUIMenu)myContainer).gotoAssignment();
    this.setVisible( false );
  }

  void jButtExtract_actionPerformed( ActionEvent e )
  {
    downBasket ();
  }

  void downBasket( )
  {
    // calls dispenser interface and extracts products in transaction
    try
    {
      myContainer.stopTimer();
   
      li_totalqty=0;
      GUIConfirmer l_contDialog = new GUIConfirmer( this, Texts.CFR_FORSURE_EXT, true );
      String ls_quest = "<p></p><p align='center'>" + Texts.CFR_CONTINUE + "</p>";
      l_contDialog.setQuestion( ls_quest );
      Config config = (Config) theSess.get(McdPrs.CONFIG);
      l_contDialog.start( new Long(config.getTimeout()).longValue() );
      if ( l_contDialog.hasExpired() ) // time expired
      {
        myContainer.timeout();
        return;
      }
      if ( l_contDialog.getSelection() == false )
      {
        if ( ((GUIMenu)myContainer).doTicket )
          ((GUIMenu)myContainer).ticket.printFooter();
        myContainer.stop();
        return;
      }
      else
      {
        // linefeeds printer
        // resets transaction panel
      }
      // resets timer
      myContainer.startTimer();
    }
    catch ( Exception ex )
    {
      McdError.add( ex );
    }
  }

}

class GUIExtraction_jButtBack_actionAdapter implements java.awt.event.ActionListener
{
  GUIExtraction adaptee;

  GUIExtraction_jButtBack_actionAdapter( GUIExtraction adaptee )
  {
    this.adaptee = adaptee;
  }

  public void actionPerformed( ActionEvent e )
  {
    adaptee.jButtBack_actionPerformed( e );
  }
}

class GUIExtraction_jButtExtract_actionAdapter implements java.awt.event.ActionListener
{
  GUIExtraction adaptee;

  GUIExtraction_jButtExtract_actionAdapter( GUIExtraction adaptee )
  {
    this.adaptee = adaptee;
  }

  public void actionPerformed( ActionEvent e )
  {
    adaptee.jButtExtract_actionPerformed( e );
  }
}
